//
// Created by shaowenhan on 2020/6/7.
//

#ifndef COMPOSITENEIGHBOR_GAIN_H
#define COMPOSITENEIGHBOR_GAIN_H

#include "DefineProblemType.h"

class Gain{
private:
    bool isPenaltyGainLessThanGiven(const Gain& gain) const
    {
        for (int i = 0; i < Constraint::num; i++)
        {
            if(isFirstLessThanSecond(penaltyGains[i], gain.penaltyGains[i]))
                return true;
            else if(isFirstGreaterThanSecond(penaltyGains[i], gain.penaltyGains[i]))
                return false;
        }
        return false;
    }
    bool isPenaltyGainEqual(const Gain& gain) const
    {
        for(int i = 0; i < Constraint::num; i++)
        {
            if(not isEqual(penaltyGains[i], gain.penaltyGains[i]))
                return false;
        }
        return true;
    }
public:
    DisType costGain;
    DisType penaltyGains[Constraint::num];

    explicit Gain(DisType defaultGain)
            : costGain(defaultGain){
        for(auto & penaltyGain : penaltyGains)
            penaltyGain = defaultGain;
    };
    explicit Gain()= default;
    bool operator==(const Gain& gain) const{
        return isEqual(costGain, gain.costGain) and isPenaltyGainEqual(gain);
    }
    bool operator<(const Gain& gain) const{
        return isFirstLessThanSecond(costGain, gain.costGain) or
               (isEqual(costGain, gain.costGain) and isPenaltyGainLessThanGiven(gain));
    }
    Gain& operator=(const Gain& gain)
    {
        if(this != &gain)
        {
            costGain = gain.costGain;
            for(int i = 0; i < Constraint::num; i++)
                penaltyGains[i] = gain.penaltyGains[i];
        }
        return *this;
    }
    Gain& operator+=(const Gain& gain){
        costGain += gain.costGain;
        for(int i = 0; i < Constraint::num; i++)
            penaltyGains[i] += gain.penaltyGains[i];
        return *this;
    }
};

#endif //COMPOSITENEIGHBOR_GAIN_H
